package luculent;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
//取年度最大值并排序
/*
1949-10-01 14:21:02	34C
1949-10-02 14:21:12	36C
1950-02-02 11:21:12	32C
1950-05-02 11:31:12	37C
1951-12-02 11:31:12	23C
1950-12-02 11:31:12	47C
1950-12-02 11:31:12	27C
1951-06-02 11:31:12	48C
1951-07-02 11:31:12	45C
 */
public class Temperature {
	/**
	 * 四个泛型类型分别代表： KeyIn Mapper的输入数据的Key，这里是每行文字的起始位置（0,11,...） ValueIn
	 * Mapper的输入数据的Value，这里是每行文字 KeyOut Mapper的输出数据的Key，这里是每行文字中的“年份” ValueOut
	 * Mapper的输出数据的Value，这里是每行文字中的“气温”
	 */
	static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	static class TempMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
		@Override
		public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
			// 打印样本: Before Mapper: 0, 2000010115
			System.out.print("Before Mapper: " + key + ", " + value);
			// 处理读取的一行数据
			String line = value.toString();
			String[] ss = line.split("\t");
			System.out.println("value=" + value.toString());
			System.out.println("ss.length=" + ss.length);
			// 只处理符合条件的数据
			if (ss.length == 2) {
				try {
					// 解析年份
					Date date = sdf.parse(ss[0]);
					Calendar c = Calendar.getInstance();
					c.setTime(date);
					// c.get(1)就是年份
					int year = c.get(1);
					System.out.println("year=" + year);
					// 解析温度
					String t = ss[1].substring(0, ss[1].indexOf("C"));
					System.out.println("t=" + t);

					// mapper写输出
					int temperature = Integer.parseInt(t);
					context.write(new Text(year+""), new IntWritable(temperature));
					// 打印样本: After Mapper:2000, 15
					System.out.println("======" + "After Mapper:" + year + ", " + temperature);
				}catch (Exception e){
					e.printStackTrace();
				}
			}





		}
	}

	/**
	 * 四个泛型类型分别代表： KeyIn Reducer的输入数据的Key，这里是每行文字中的“年份” ValueIn
	 * Reducer的输入数据的Value，这里是每行文字中的“气温” KeyOut Reducer的输出数据的Key，这里是不重复的“年份”
	 * ValueOut Reducer的输出数据的Value，这里是这一年中的“最高气温”
	 */
	static class TempReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
		@Override
		public void reduce(Text key, Iterable<IntWritable> values, Context context)
				throws IOException, InterruptedException {
			int maxValue = Integer.MIN_VALUE;
			StringBuffer sb = new StringBuffer();
			// 取values的最大值
			for (IntWritable value : values) {
				maxValue = Math.max(maxValue, value.get());
				sb.append(value).append(", ");
			}
			// 打印样本： Before Reduce: 2000, 15, 23, 99, 12, 22,
			System.out.print("Before Reduce: " + key + ", " + sb.toString());
			context.write(key, new IntWritable(maxValue));
			// 打印样本： After Reduce: 2000, 99
			System.out.println("======" + "After Reduce: " + key + ", " + maxValue);
		}
	}

	public static void main(String[] args) throws Exception {
		// 输入路径
		String dst = "hdfs://localhost:9000/user/output1/";
		// 输出路径，必须是不存在的，空文件加也不行。
		String dstOut = "hdfs://localhost:9000/user/output1/";
		Configuration conf = new Configuration();
		conf.set("mapred.job.tracker", "localhost:9000");

		//HdfsUtils.mkdir("/user/dedup_in");
		//HdfsUtils.mkdir("/user/dedup_out");
		HdfsUtils.deleteDir("/user/dedup_out");
		//HdfsUtils.uploadLocalFile2HDFS("E:/code/workspace/hadoopone/src/main/java/temperature/input/data","/user/dedup_in/data");
		String[] ioArgs = new String[]{"hdfs://localhost:9000/user/dedup_in", "hdfs://localhost:9000/user/dedup_out"};
	/*	conf.set("fs.hdfs.impl", org.apache.hadoop.hdfs.DistributedFileSystem.class.getName());
		conf.set("fs.file.impl", org.apache.hadoop.fs.LocalFileSystem.class.getName());*/
		Job job = Job.getInstance(conf);

		// 如果需要打成jar运行，需要下面这句
		// job.setJarByClass(NewMaxTemperature.class);

		// job执行作业时输入和输出文件的路径
		FileInputFormat.addInputPath(job, new Path(ioArgs[0]));
		FileOutputFormat.setOutputPath(job, new Path(ioArgs[1]));

		// 指定自定义的Mapper和Reducer作为两个阶段的任务处理类
		job.setMapperClass(TempMapper.class);
		job.setReducerClass(TempReducer.class);

		// 设置最后输出结果的Key和Value的类型
		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(IntWritable.class);

		// 执行job，直到完成
		job.waitForCompletion(true);
		System.out.println("Finished");
	}
}